/////////////////////////////////////////////////////////////////////////
// $Id: compiler.h 10613 2012-06-21 16:44:02Z xint $
/////////////////////////////////////////////////////////////////////////
//
//   Copyright (c) 2007-2011 Stanislav Shwartsman
//          Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////

#ifndef BX_COMPILER_H
#define BX_COMPILER_H

#include "bochs.h"
#include "cpu.h"
#include "jit.h"
#include "stats.h"

#include <dlfcn.h>    // for dlopen, dlsym, etc.
#include <pthread.h>  // for pthread_create, etc.
#include <vector>     // for compilation queue.

#define BX_COMPILER_THIS_PTR  this->

///--------------------------------------------------------------
/// @ BX_COMP_C - this class implements the interface 
//  @ between the interpreter and the JIT compiler. It 
//  @ implements the compilation queue and compilation 
//  @ thread. It also implements an interface for driving
//  @ the JIT compiler.
///--------------------------------------------------------------
class BX_COMP_C : public logfunctions 
{
public:
/// status of the compilation thread. 
#define COMP_WAITING   0x1
#define COMP_COMPILING 0x2

/// should the compilation thread keep running ?
#define COMP_RUN       0x1
#define COMP_STOP      0x2 

/// compilation unit initialization status.
#define COMP_INIT_UNCALLED   0x1
#define COMP_INIT_UNNEEDED   0x2
#define COMP_INIT_FAILED     0x3
#define COMP_INIT_SUCCESSFUL 0x4

public:
public:
  typedef std::vector<bxICacheEntry_c*> bxICaches_t; 

public:
  Bit32u           init_status;    // init status.
  Bit32u           run_status;     // running status.
  Bit32u           work_status;    // working status.
  pthread_t        thread_id;      // pthread id. 

  Bit8u*           lib_path;       // library path.       
  void*            lib_handle;     // shared library handle.

  bxICaches_t      pending_entries;// entries pending.
  bxICaches_t      finish_entries; // entries finished.
  bxICaches_t      reject_entries; // entries rejected.

  bxICacheEntry_c* current;        // currently compiling entry.

  pthread_mutex_t  queue_mutex;    // guards compilation queue.
  pthread_cond_t   queue_cond;     // compilation thread waits on.

  inp_callbacks    i_callbacks;    // INT callbacks.
  jit_callbacks    j_callbacks;    // JIT callbacks.
  BX_JIT_C         jit_code;       // Code use to communicate with JIT.

  bxCOMPStats_c*   stats;          // Stats object.

public:
  // ========================================
  // constructor and destructor.
  // ========================================
  BX_COMP_C(void) : init_status(COMP_INIT_UNCALLED), 
                    lib_handle(0), thread_id(0), current(0), stats(0) 
  {
    pthread_cond_init(&queue_cond, NULL);
    pthread_mutex_init(&queue_mutex, NULL);
    stats = new bxCOMPStats_c;
  }

  // ========================================
  // initialize the compilation thread.
  // ========================================
  void initialize_prefix(void); 
  void initialize(Bit8u* lib_path);
  void deinitialize(void); 
  void initialize_jit_func(void);
  void initialize_int_func(void);
  bx_bool initialize_library(void);
  bx_bool initialize_thread(void); 

  // ========================================
  // functions to drive the compilation.
  // ========================================
  void compile(bxICacheEntry_c *trace);
  void compiler_run(void); 
  void compiler_submit(bxICacheEntry_c *request);

  // ========================================
  // manage invalid entries.
  // ========================================
  void flushICacheEntries(void);
  void flushICacheEntry(bxICacheEntry_c *request);
};

#endif
